#include "Function.hpp"
#include "EquationSolver.hpp"
#include <iostream>
#include <cmath>

const double Pi = acos(-1.);

class F : public Function {
public:
    double operator() (double x) const {
        return L*(0.5*Pi*pow(r,2)-pow(r,2)*asin(x/r)-x*pow(r*r-x*x,0.5)) - V;
    }
    double derivative(double x) const {
        return -2*L*pow(r*r-x*x,0.5);
    }
    double L = 10;
    double r = 1;
    double V = 12.4;
};


void solve_f_1() {
    // a = 0, b = 1
    std::cout << "Solving with Bisection Method" << std::endl;
    Bisection_Method solver_f_1(F(), 0, 1);
    double x1 = solver_f_1.solve();
    std::cout << "A root is: " << x1 << std::endl;
}

void solve_f_2() {
    // x0 = 0.5
    std::cout << "Solving with Newton Method" << std::endl;
    Newton_Method solver_f_2(F(), 0.5);
    double x2 = solver_f_2.solve();
    std::cout << "A root is: " << x2 << std::endl;
}

void solve_f_3() {
    // x0 = 0.5, x1 = 0.6
    std::cout << "Solving with Secant Method" << std::endl;
    Secant_Method solver_f_3(F(), 0.5, 0.6);
    double x3 = solver_f_3.solve();
    std::cout << "A root is: " << x3 << std::endl;
}

/* Type your code here */

int main() {
    solve_f_1();
    solve_f_2();
    solve_f_3();
    /* Type your code here */
    return 0;
}